/**
 * 视频辅助工具 - 负责视频相关的计算和处理
 */

/**
 * 视频显示区域
 */
export interface VideoDisplayRect {
  left: number
  top: number
  width: number
  height: number
}

/**
 * 视频辅助工具类
 */
export class VideoHelper {
  private container: HTMLElement
  private video?: HTMLVideoElement

  constructor(container: HTMLElement, video?: HTMLVideoElement) {
    this.container = container
    this.video = video
  }

  /**
   * 更新视频元素
   */
  updateVideo(video?: HTMLVideoElement): void {
    this.video = video
  }

  /**
   * 计算视频的实际显示区域
   * 考虑 object-fit: contain 的情况
   */
  getVideoDisplayRect(): VideoDisplayRect {
    if (!this.video) {
      // 如果没有视频元素，使用容器的完整区域
      const rect = this.container.getBoundingClientRect()
      return { left: 0, top: 0, width: rect.width, height: rect.height }
    }

    const containerRect = this.container.getBoundingClientRect()
    
    // 获取视频的原始尺寸
    const videoWidth = this.video.videoWidth
    const videoHeight = this.video.videoHeight
    
    if (videoWidth === 0 || videoHeight === 0) {
      // 视频还没有加载，使用容器区域
      return { left: 0, top: 0, width: containerRect.width, height: containerRect.height }
    }

    // 计算视频在容器中的实际显示区域（考虑object-fit: contain）
    const containerAspect = containerRect.width / containerRect.height
    const videoAspect = videoWidth / videoHeight

    let displayWidth: number
    let displayHeight: number
    let displayLeft: number
    let displayTop: number

    if (videoAspect > containerAspect) {
      // 视频更宽，以宽度为准
      displayWidth = containerRect.width
      displayHeight = containerRect.width / videoAspect
      displayLeft = 0
      displayTop = (containerRect.height - displayHeight) / 2
    } else {
      // 视频更高，以高度为准
      displayHeight = containerRect.height
      displayWidth = containerRect.height * videoAspect
      displayTop = 0
      displayLeft = (containerRect.width - displayWidth) / 2
    }

    return {
      left: displayLeft,
      top: displayTop,
      width: displayWidth,
      height: displayHeight
    }
  }

  /**
   * 获取视频宽高比
   */
  getVideoAspectRatio(): number {
    if (!this.video) return 16 / 9 // 默认宽高比

    const videoWidth = this.video.videoWidth
    const videoHeight = this.video.videoHeight

    if (videoWidth === 0 || videoHeight === 0) {
      return 16 / 9 // 默认宽高比
    }

    return videoWidth / videoHeight
  }

  /**
   * 检查视频是否已加载
   */
  isVideoLoaded(): boolean {
    if (!this.video) return false
    return this.video.videoWidth > 0 && this.video.videoHeight > 0
  }

  /**
   * 获取视频当前播放时间
   */
  getCurrentTime(): number {
    return this.video?.currentTime ?? 0
  }

  /**
   * 检查视频是否正在播放
   */
  isVideoPlaying(): boolean {
    if (!this.video) return false
    return !this.video.paused && !this.video.ended && this.video.readyState > 2
  }

  /**
   * 获取视频原始尺寸
   */
  getVideoNaturalSize(): { width: number; height: number } {
    if (!this.video) {
      return { width: 0, height: 0 }
    }
    return {
      width: this.video.videoWidth,
      height: this.video.videoHeight
    }
  }

  /**
   * 将视频坐标转换为显示坐标
   * @param videoX 视频原始 X 坐标
   * @param videoY 视频原始 Y 坐标
   */
  videoToDisplayCoordinates(videoX: number, videoY: number): { x: number; y: number } {
    const videoRect = this.getVideoDisplayRect()
    const naturalSize = this.getVideoNaturalSize()

    if (naturalSize.width === 0 || naturalSize.height === 0) {
      return { x: videoX, y: videoY }
    }

    const scaleX = videoRect.width / naturalSize.width
    const scaleY = videoRect.height / naturalSize.height

    return {
      x: videoX * scaleX,
      y: videoY * scaleY
    }
  }

  /**
   * 将显示坐标转换为视频坐标
   * @param displayX 显示 X 坐标
   * @param displayY 显示 Y 坐标
   */
  displayToVideoCoordinates(displayX: number, displayY: number): { x: number; y: number } {
    const videoRect = this.getVideoDisplayRect()
    const naturalSize = this.getVideoNaturalSize()

    if (naturalSize.width === 0 || naturalSize.height === 0) {
      return { x: displayX, y: displayY }
    }

    const scaleX = videoRect.width / naturalSize.width
    const scaleY = videoRect.height / naturalSize.height

    return {
      x: displayX / scaleX,
      y: displayY / scaleY
    }
  }
}

